<script setup lang="ts">
import {onMounted, reactive, ref} from "vue"
import {Refresh} from "@element-plus/icons-vue";
import {getClusterInfo, health, nodeMetrics} from "@/views/api/elastic.ts"
import {createDefaultHealth, createHealth, Health} from "@/views/types/health.ts";
import Point from "@/components/Point.vue";

import {useSiteStore} from "@/store/modules/site.ts";
import ClusterInfoContent from "@/views/components/ClusterInfoContent.vue";
import HealthContent from "@/views/components/HealthContent.vue";
import {Charts, createNodeMetrics, Metrics, NodeMetrics} from "@/views/types/node.ts";
import moment from "moment";
// import MetricsContent from "@/views/components/MetricsContent.vue";

const view = ref<Health>(createDefaultHealth())
const loading = ref(false);
const type = ref<string>("metrics");
const interval = ref(15 * 1000);
const records = ref<Array<Metrics>>([]);
const nodeCharts = ref<Record<string, Charts>>({});
const clusterInfo = ref<Record<string, any>>({});
const cpu = ref<Charts>({
  title:"CPU使用率",
  times: [],
  series: []
})
const memory = ref<Charts>({
  title:"内存使用率",
  times: [],
  series: []
})
const headMemory = ref<Charts>({
  title:"堆内存使用率",
  times: [],
  series: []
})
const disk = ref<Charts>({
  title:"磁盘使用率",
  times: [],
  series: []
})
const load1 = ref<Charts>({
  title:"1分钟负载",
  times: [],
  series: []
})
const load5 = ref<Charts>({
  title:"5分钟负载",
  times: [],
  series: []
})
const load15 = ref<Charts>({
  title:"15分钟负载",
  times: [],
  series: []
})
const times = reactive([
  {value: -1, label: "None"},
  {value: 15 * 1000, label: "15秒"},
  {value: 30 * 1000, label: "30秒"},
  {value: 60 * 1000, label: "1分"},
])
let timer = null;
const queryHealth = () => {
  health().then((data) => {
    view.value = createHealth(data)
    useSiteStore().setHealth(view.value.status)
  })
}
const queryClusterInfo = () => {
  getClusterInfo().then((data) => {
    clusterInfo.value ={};
    const map={};
    Object.keys(data).forEach(key => {
      if(key==='version'){
        const values=data[key];
        Object.keys(values).forEach(k => {
          map['version.'+k]=values[k];
        })
      }else{
        map[key]=data[key];
      }
    })
    clusterInfo.value=map;
  })
}
const resetCharts = () => {
  const times = records.value.map(d => d.label);
  nodeCharts.value={};
  cpu.value.times = times;
  cpu.value.series = [];
  memory.value.times = times;
  memory.value.series = [];
  headMemory.value.times = times;
  headMemory.value.series = [];
  disk.value.times = times;
  disk.value.series = [];
  load1.value.times = times;
  load1.value.series = [];
  load5.value.times = times;
  load5.value.series = [];
  load15.value.times = times;
  load15.value.series = [];
  const items:Array<NodeMetrics>=[];
  let rows: Map<string, Array<NodeMetrics>> = new Map<string, Array<NodeMetrics>>();
  records.value.forEach((item) => {
    const values = item.values;
    values.forEach((node) => {
      let list=rows.get(node.name);
      if(!list){
        list=[];
        list.push(node);
        items.push(node);
        rows.set(node.name, list);
      }else{
        items.push(node);
        list.push(node);
      }
    })
  })
  rows= new Map(
      Array.from(rows.entries()).sort((a, b) => a[0].localeCompare(b[0]))
  );
  rows.forEach((values,key) => {
    nodeCharts.value[key]={
      title: key,
      times: times,
      series: [
          {
            name:"堆内存使用率",
            data:items.filter(d=>d.name===key).map(i=>Number(i.headMemoryPercent))
          },
          {
            name:"内存使用率",
            data:items.filter(d=>d.name===key).map(i=>Number(i.memoryPercent))
          },
          {
            name:"CPU使用率",
            data:items.filter(d=>d.name===key).map(i=>Number(i.cpuPercent))
          },
          {
            name:"磁盘使用率",
            data:items.filter(d=>d.name===key).map(i=>Number(i.diskPercent))
          },
          {
            name:"1分钟负载",
            data:items.filter(d=>d.name===key).map(i=>Number(i.load1))
          },
          {
            name:"5分钟负载",
            data:items.filter(d=>d.name===key).map(i=>Number(i.load5))
          },
          {
            name:"15分钟负载",
            data:items.filter(d=>d.name===key).map(i=>Number(i.load15))
          },
        ]
      }
    cpu.value.series.push({
      name:key,
      data:values.map(d=>Number(d.cpuPercent))
    })
    memory.value.series.push({
      name:key,
      data:values.map(d=>Number(d.memoryPercent))
    })
    headMemory.value.series.push({
      name:key,
      data:values.map(d=>Number(d.headMemoryPercent))
    })
    disk.value.series.push({
      name:key,
      data:values.map(d=>Number(d.diskPercent))
    })
    load1.value.series.push({
      name:key,
      data:values.map(d=>Number(d.load1))
    })
    load5.value.series.push({
      name:key,
      data:values.map(d=>Number(d.load5))
    })
    load15.value.series.push({
      name:key,
      data:values.map(d=>Number(d.load15))
    })
  })
}
const queryMetrics = () => {
  nodeMetrics().then((data) => {
    const time = moment().format("mm:ss");
    const values = data.map(item => createNodeMetrics(item, time));
    if (records.value.length >= 30) {
      records.value.shift();
    }
    records.value.push({label: time, values: values});
    resetCharts();
  })
}
const setTimer = () => {
  clearInterval(timer);
  if (interval.value > 0) {
    timer = setInterval(() => {
      query();
    }, interval.value);
  }
}
onMounted(() => {
  query();
  setTimer();
})
const query = () => {
  queryClusterInfo();
  queryHealth();
  //queryMetrics();
}
</script>

<template>
  <el-card class="box-card">
    <template #header>
      <div class="card-header">
        <span><Point :color="view.status"/> {{ view.clusterName }}</span>
        <div>
          <el-button :icon="Refresh" text @click="query"></el-button>
          <el-select v-model="interval" style="width: 70px;--el-border-color: #00000000;" @change="setTimer">
            <el-option v-for="item in times" :key="item.value" :value="item.value" :label="item.label"></el-option>
          </el-select>
        </div>
      </div>
    </template>
    <div v-loading="loading">
      <ClusterInfoContent :records="clusterInfo"/>
      <HealthContent :view="view"/>
<!--      <div style="display: flex;justify-content: space-between;align-items: center;">-->
<!--        <div class="item-title">性能数据</div>-->
<!--        <div>-->
<!--          <el-radio-group v-model="type">-->
<!--            <el-radio-button value="metrics">指标</el-radio-button>-->
<!--            <el-radio-button value="node">节点</el-radio-button>-->
<!--          </el-radio-group>-->
<!--        </div>-->
<!--      </div>-->
<!--      <div v-if="type==='metrics'">-->
<!--        <MetricsContent :charts="headMemory"/>-->
<!--        <MetricsContent :charts="memory"/>-->
<!--        <MetricsContent :charts="cpu"/>-->
<!--        <MetricsContent :charts="disk"/>-->
<!--        <MetricsContent :charts="load1"/>-->
<!--        <MetricsContent :charts="load5"/>-->
<!--        <MetricsContent :charts="load15"/>-->
<!--      </div>-->
<!--      <div v-else>-->
<!--        <template v-for="chart in nodeCharts">-->
<!--          <MetricsContent :charts="chart"/>-->
<!--        </template>-->
<!--      </div>-->
    </div>
  </el-card>
</template>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
}

.item-title {
  width: 200px;
  color: var(--el-text-color-primary);
  font-size: 16px;
  font-weight: bold;
  margin-top: 12px;
  margin-bottom: 12px;
}
</style>